cmake_minimum_required(VERSION 3.10)
project(GameServer CXX)

# 设置默认安装路径为项目本地目录（方便打包分发）
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install" CACHE PATH "Install path" FORCE)
endif()

# C++11 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2")

# muduo 库路径
set(MUDUO_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
set(MUDUO_LIB_DIR ${CMAKE_SOURCE_DIR}/lib)

include_directories(${MUDUO_INCLUDE_DIR})
link_directories(${MUDUO_LIB_DIR})

# 包含项目目录
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/third_party)

# 查找 Protobuf
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})

# 生成 protobuf 文件
set(PROTO_FILES
    ${CMAKE_SOURCE_DIR}/protocol/proto/echo.proto
    ${CMAKE_SOURCE_DIR}/protocol/proto/chat.proto
)

# 设置生成的文件输出目录
set(PROTO_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/protocol/proto)

# 使用 protoc 生成 .pb.cc 和 .pb.h
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})

# 将生成的文件添加到包含路径
include_directories(${CMAKE_CURRENT_BINARY_DIR})

# 公共配置库
add_library(common STATIC
    common/config/ServerConfig.cpp
)
target_include_directories(common
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
        $<INSTALL_INTERFACE:include/gameserver>
)
target_link_libraries(common
    pthread
    stdc++
)

# 网络层库
add_library(network STATIC
    network/Session.cpp
    network/SessionManager.cpp
    network/NetworkServer.cpp
)
target_include_directories(network
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
        $<INSTALL_INTERFACE:include/gameserver>
)
target_link_libraries(network
    muduo_net
    muduo_base
    pthread
    stdc++
)

# 协议层库
add_library(protocol STATIC
    protocol/MessageCodec.cpp
    ${PROTO_SRCS}
)
target_include_directories(protocol
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
        $<INSTALL_INTERFACE:include/gameserver>
)
target_link_libraries(protocol 
    muduo_net 
    muduo_base 
    ${PROTOBUF_LIBRARIES}
    pthread
    stdc++
)

# 服务器框架库
add_library(server_framework STATIC
    server/BaseServer.cpp
)
target_include_directories(server_framework
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
        $<INSTALL_INTERFACE:include/gameserver>
)
target_link_libraries(server_framework
    common
    network
    protocol
    muduo_net
    muduo_base
    ${PROTOBUF_LIBRARIES}
    pthread
    stdc++
)

# Echo Server（阶段2版本 - 保留用于对比）
add_executable(echo_server_old
    servers/echo/echo_server.cpp
)
target_link_libraries(echo_server_old
    protocol
    muduo_net 
    muduo_base 
    ${PROTOBUF_LIBRARIES}
    pthread
    stdc++
)

# Echo Server（阶段3版本 - 使用 BaseServer 框架）
add_executable(echo_server
    servers/echo/main.cpp
)
target_link_libraries(echo_server
    server_framework
    common
    network
    protocol
    ${PROTOBUF_LIBRARIES}
    muduo_net
    muduo_base
    pthread
    stdc++
    rt
)

# Echo Client (测试客户端)
add_executable(echo_client 
    servers/echo/echo_client.cpp
)
target_link_libraries(echo_client 
    protocol
    muduo_net 
    muduo_base 
    ${PROTOBUF_LIBRARIES}
    pthread
    stdc++
)

# Chat Server（阶段4版本 - 使用 BaseServer 框架实战）
add_executable(chat_server
    servers/chat/main.cpp
)
target_link_libraries(chat_server
    server_framework
    common
    network
    protocol
    ${PROTOBUF_LIBRARIES}
    muduo_net
    muduo_base
    pthread
    stdc++
    rt
)

# Chat Client（测试客户端）
add_executable(chat_client
    servers/chat/chat_client.cpp
)
target_link_libraries(chat_client
    protocol
    muduo_net
    muduo_base
    ${PROTOBUF_LIBRARIES}
    pthread
    stdc++
)

# 打印信息
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "Protobuf version: ${PROTOBUF_VERSION}")
message(STATUS "Protobuf libraries: ${PROTOBUF_LIBRARIES}")
message(STATUS "Generated proto sources: ${PROTO_SRCS}")
message(STATUS "Generated proto headers: ${PROTO_HDRS}")

#===============================================================================
# 阶段5：库化配置
# 只安装框架库文件，不安装测试程序（echo_server, chat_server, echo_client, chat_client）
#===============================================================================

# 安装库文件到 lib 目录
install(TARGETS server_framework network protocol common
        EXPORT GameServerFrameworkTargets
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin)

# 安装头文件到 include/gameserver（保留目录结构）
install(DIRECTORY 
        common
        network
        protocol
        server
        DESTINATION include/gameserver
        FILES_MATCHING PATTERN "*.h"
        PATTERN "*.cpp" EXCLUDE
        PATTERN "proto" EXCLUDE)

# 安装 third_party 头文件（nlohmann/json）
install(DIRECTORY 
        third_party/
        DESTINATION include/gameserver/third_party
        FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h")

# 安装 muduo 头文件（支持即拿即用，无需在新系统安装 muduo）
if(EXISTS "${CMAKE_SOURCE_DIR}/include/muduo")
    install(DIRECTORY
            ${CMAKE_SOURCE_DIR}/include/muduo
            DESTINATION include)
    message(STATUS "  - Muduo headers: FOUND at ${CMAKE_SOURCE_DIR}/include/muduo")
    message(STATUS "  - Headers will be installed to: ${CMAKE_INSTALL_PREFIX}/include/muduo")
else()
    message(WARNING "  - Muduo headers: NOT FOUND at ${CMAKE_SOURCE_DIR}/include/muduo")
endif()

# 安装 muduo 库文件（支持即拿即用，无需在新系统安装 muduo）
if(EXISTS "${CMAKE_SOURCE_DIR}/lib/libmuduo_net.a")
    install(FILES
            ${CMAKE_SOURCE_DIR}/lib/libmuduo_net.a
            ${CMAKE_SOURCE_DIR}/lib/libmuduo_base.a
            DESTINATION lib)
    message(STATUS "  - Muduo libraries: FOUND at ${CMAKE_SOURCE_DIR}/lib/")
    message(STATUS "  - muduo_net and muduo_base will be installed to: ${CMAKE_INSTALL_PREFIX}/lib/")
else()
    message(WARNING "  - Muduo libraries: NOT FOUND at ${CMAKE_SOURCE_DIR}/lib/")
endif()

# 安装 protoc 编译器到 bin 目录（支持即拿即用，无需在新系统安装 protobuf）
# 解析软链接，安装实际的可执行文件
execute_process(
    COMMAND readlink -f /usr/local/bin/protoc
    OUTPUT_VARIABLE PROTOC_REAL_PATH
    OUTPUT_STRIP_TRAILING_WHITESPACE
    ERROR_QUIET
)

if(EXISTS "${PROTOC_REAL_PATH}")
    install(PROGRAMS ${PROTOC_REAL_PATH}
            DESTINATION bin
            RENAME protoc)
    message(STATUS "  - Protoc compiler: FOUND at ${PROTOC_REAL_PATH}")
    message(STATUS "  - Protoc will be installed to: ${CMAKE_INSTALL_PREFIX}/bin/protoc")
else()
    message(WARNING "  - Protoc compiler: NOT FOUND")
    message(WARNING "  - Users will need to install protobuf manually")
endif()

# 安装 protobuf 库文件（支持新系统无需安装 protobuf）
if(EXISTS "/usr/local/lib64/libprotobuf.a")
    install(FILES
            /usr/local/lib64/libprotobuf.a
            /usr/local/lib64/libprotobuf-lite.a
            /usr/local/lib64/libprotoc.a
            DESTINATION lib)
    message(STATUS "  - Protobuf libraries: FOUND at /usr/local/lib64/")
    message(STATUS "  - Libraries will be installed to: ${CMAKE_INSTALL_PREFIX}/lib/")
else()
    message(WARNING "  - Protobuf libraries: NOT FOUND at /usr/local/lib64/")
endif()

# 安装 protobuf 头文件
if(EXISTS "/usr/local/include/google")
    install(DIRECTORY
            /usr/local/include/google
            DESTINATION include)
    message(STATUS "  - Protobuf headers: FOUND at /usr/local/include/google")
    message(STATUS "  - Headers will be installed to: ${CMAKE_INSTALL_PREFIX}/include/google")
else()
    message(WARNING "  - Protobuf headers: NOT FOUND at /usr/local/include/google")
endif()

# 导出目标到 GameServerFrameworkTargets
install(EXPORT GameServerFrameworkTargets
        FILE GameServerFrameworkTargets.cmake
        NAMESPACE GameServerFramework::
        DESTINATION lib/cmake/GameServerFramework)

# 生成并安装 Config 文件
include(CMakePackageConfigHelpers)
configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GameServerFrameworkConfig.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/GameServerFrameworkConfig.cmake
    INSTALL_DESTINATION lib/cmake/GameServerFramework
)

# 生成版本文件
write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/GameServerFrameworkConfigVersion.cmake
    VERSION 1.0.0
    COMPATIBILITY AnyNewerVersion
)

# 安装 CMake 配置文件
install(FILES
        ${CMAKE_CURRENT_BINARY_DIR}/GameServerFrameworkConfig.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/GameServerFrameworkConfigVersion.cmake
        DESTINATION lib/cmake/GameServerFramework)

# 安装使用文档
install(FILES
        ${CMAKE_CURRENT_SOURCE_DIR}/USAGE.md
        DESTINATION .)

# 后处理：修复 GameServerFrameworkTargets.cmake 中的硬编码路径
# 将系统 protobuf 路径替换为打包后的相对路径
install(CODE "
    set(TARGETS_FILE \"${CMAKE_INSTALL_PREFIX}/lib/cmake/GameServerFramework/GameServerFrameworkTargets.cmake\")
    if(EXISTS \"\${TARGETS_FILE}\")
        file(READ \"\${TARGETS_FILE}\" FILE_CONTENT)
        # 替换硬编码的系统 protobuf 路径为相对路径
        string(REPLACE \"/usr/local/lib64/libprotobuf.a\" \"\\\${_IMPORT_PREFIX}/lib/libprotobuf.a\" FILE_CONTENT \"\${FILE_CONTENT}\")
        file(WRITE \"\${TARGETS_FILE}\" \"\${FILE_CONTENT}\")
        message(STATUS \"Fixed protobuf paths in GameServerFrameworkTargets.cmake\")
    endif()
")

message(STATUS "===============================================")
message(STATUS "  Framework will be installed to:")
message(STATUS "  - Libraries: ${CMAKE_INSTALL_PREFIX}/lib")
message(STATUS "  - Headers: ${CMAKE_INSTALL_PREFIX}/include/gameserver")
message(STATUS "  - Binaries: ${CMAKE_INSTALL_PREFIX}/bin (protoc)")
message(STATUS "  - CMake configs: ${CMAKE_INSTALL_PREFIX}/lib/cmake/GameServerFramework")
message(STATUS "===============================================")

